/*
 * @Author: 缄默
 * @Date: 2021-12-12 15:17:07
 * @LastEditors: 缄默
 * @LastEditTime: 2022-01-27 14:00:58
 */

//迭代器模式

#include <iostream>
#include <vector>
#include <list>

using namespace std;

class Iterator {
public:
    virtual ~Iterator() { }

    virtual int next() = 0;

    virtual bool hasNext() = 0;

    virtual int currentItem() = 0;
};

//一个具体迭代器应该对应一个具体的数据结构
class ConcreteAggregateIterator1 : public Iterator {
private:
    vector<int> _vector;
    int _index;
public:

    ConcreteAggregateIterator1(vector<int>& vector) : _index(0) {
        _vector = vector;
    }

    int next() {
        if (hasNext()) {
            int num = currentItem();
            ++_index;
            return num;
        }
    }

    bool hasNext() {
        if (_index < _vector.size()) {
            return true;
        }

        return false;
    }
    int currentItem() {
        return _vector[_index];
    }

    int currentItem(int index) {
        return _vector[index];
    }
};

class ConcreteAggregateIterator2 : public Iterator {
private:
    list<int> _list;
    list<int>::const_iterator _iter;
public:

    ConcreteAggregateIterator2(list<int>& list) {
        _list = list;
        _iter = _list.begin();
    }

    int next() {
        if (hasNext()) {
            int num = currentItem();
            _iter++;
            return num;
        }
        cout << " no element." << endl;
        return 0;
    }

    bool hasNext() {
        if (_iter != _list.end()) {
            return true;
        }
        return false;
    }

    int currentItem() {
        return *_iter;
    }
};

//此处可以写成模板的形式 这样这个聚合类接受具体的不同的类型
//但要有所区分的是聚合类展现的是一种数据结构，而不是一种数据类型
//这个地方要进行理解 为了简便这里采用int作为数据类型
//<typename T>
class Aggregate {
public:
    //这个地方也要理解 我们返回的是一个具体的迭代器，
    //并没有加入替换迭代器以实现修改遍历方式的实现
    //想要这个实现可以在返回迭代器之前结合策略模式把这个地方给修改
    virtual Iterator* createIterator() = 0;
};


//具体的数据结构是被封装起来的
class ConcreteAggregate1 : public Aggregate {
private:
    //这里代表这个聚会类是以vector形式的聚合
    vector<int> _vector;
public:

    ConcreteAggregate1(vector<int>& vector){
        _vector = vector;
    }

    //为了隐藏细节，聚合的数据要能给出对应的迭代器
    Iterator* createIterator() {
        return new ConcreteAggregateIterator1(_vector);
    }
};

class ConcreteAggregate2 : public Aggregate {
private:
    //这里代表这个聚会类是以列表形式的聚合
    list<int> _list;
public:
    ConcreteAggregate2(list<int>& list) {
        _list = list;
    }


    Iterator* createIterator() {
        return new ConcreteAggregateIterator2(_list);
    }
};


//从此类来看封装了两个aggregate的内部结构，统一采用迭代器进行遍历
class Iter {
public:
    Iter(Aggregate* agg1, Aggregate* agg2) {
        _aggregate1 = agg1;
        _aggregate2 = agg2;
    }

    void printAggregate() const {
        printAggregate(_aggregate1->createIterator());
        printAggregate(_aggregate2->createIterator());
    }

private:
    void printAggregate(Iterator* iter) const {
        while(iter->hasNext()) {
            cout << iter->next() << " ";
        }
    }

private:
    Aggregate *_aggregate1;
    Aggregate *_aggregate2;
};

int main() {
    vector<int> _vec({1, 2, 3, 4});
    list<int> _list({5, 6, 7, 8});
    Aggregate* agg1 = new ConcreteAggregate1(_vec);
    Aggregate* agg2 = new ConcreteAggregate2(_list);

    Iter* ite = new Iter(agg1, agg2);
    ite->printAggregate();
    return 0;
}
